package org.lx.nursing.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.lx.common.exception.base.BaseException;
import org.lx.nursing.domain.Bed;
import org.lx.nursing.domain.CheckIn;
import org.lx.nursing.domain.Contract;
import org.lx.nursing.domain.Elder;
import org.lx.nursing.dto.CheckInApplyDto;
import org.lx.nursing.mapper.*;
import org.lx.nursing.service.ICheckInService;
import org.lx.nursing.util.CheckInUtil;
import org.lx.nursing.util.CodeGenerator;
import org.lx.nursing.vo.CheckInConfigVo;
import org.lx.nursing.vo.CheckInDetailVo;
import org.lx.nursing.vo.CheckInElderVo;
import org.lx.nursing.vo.ElderFamilyVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 入住Service业务层处理
 *
 * @author lx
 * @date 2025-02-28
 */
@Service
@Slf4j
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService {
    @Autowired
    private CheckInMapper checkInMapper;

    @Autowired
    private ElderMapper elderMapper;

    @Autowired
    private BedMapper bedMapper;

    @Resource
    private ContractMapper contractMapper;

    @Resource
    private CheckInConfigMapper checkInConfigMapper;

    @Resource
    private CheckInUtil checkInUtil;

    @Override
    public CheckIn selectCheckInById(Long id) {
        return getById(id);
    }

    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn) {
        return checkInMapper.selectCheckInList(checkIn);
    }

    @Override
    public int insertCheckIn(CheckIn checkIn) {
        return save(checkIn) ? 1 : 0;
    }

    @Override
    public int updateCheckIn(CheckIn checkIn) {
        return updateById(checkIn) ? 1 : 0;
    }

    @Override
    public int deleteCheckInByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    @Override
    public int deleteCheckInById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 入住申请
     *
     * @see CheckInUtil
     */
    @Override
    @Transactional
    public void apply(CheckInApplyDto dto) {
        // 通过身份证号判断老人是否已经入住
        LambdaQueryWrapper<Elder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Elder::getIdCardNo, dto.getCheckInElderDto().getIdCardNo());
        wrapper.eq(Elder::getStatus, 1);
        Elder elder = elderMapper.selectOne(wrapper);
        if (ObjectUtils.isNotEmpty(elder)) throw new BaseException("该老人已经入住");
        // 设置床位
        Bed bed = bedMapper.selectBedById(dto.getCheckInConfigDto().getBedId());
        bed.setBedStatus(1);
        bedMapper.updateBed(bed);
        // 新增/更新老人
        elder = checkInUtil.insertOrUpdate(bed, dto.getCheckInElderDto());
        // 生成合同
        String contractNo = "HT" + CodeGenerator.generateContractNumber();
        // 签约办理
        checkInUtil.insertContract(contractNo, elder, dto);
        // 新增入住信息
        CheckIn checkIn = checkInUtil.insertCheckIn(elder, dto);
        // 新增入住配置
        checkInUtil.insertCheckInConfig(checkIn.getId(), dto);
    }

    /**
     * 入住详情(传入id为check_in主键)
     */
    @Override
    public CheckInDetailVo detail(Long id) {
        CheckInConfigVo checkInConfigVo = checkInConfigMapper.selectConfigVoByInId(id);
        String bedNumber = checkInConfigVo.getBedNumber();
        CheckInElderVo checkInElderVo = checkInMapper.selectCheckInByBedNumber(bedNumber);
        if (ObjectUtils.isEmpty(checkInElderVo)){
            throw new BaseException("信息异常!!请联系管理员");
        }
        checkInElderVo.setAge(checkInElderVo.getAge());
        Long elderId = checkInElderVo.getId();
        List<ElderFamilyVo> list = checkInMapper.elderFamilyVoList(elderId);
        Contract contract = contractMapper.selectContractByElderId(elderId);
        return CheckInDetailVo.builder()
                .checkInElderVo(checkInElderVo)
                .elderFamilyVoList(list)
                .checkInConfigVo(checkInConfigVo)
                .contract(contract)
                .build();
    }
}
